<?php
/**
 * PrynLib
 * @copyright 2007-2009 Prynel
 * @author Olivier ROGER <roger.olivier@gmail.com>
 * @category libPrynel
 * @package Net
 * @version $Revision: 121 $
 */

/**
 * Base pour la comunication sur socket
 * @category libPrynel
 * @package Net
 * @version 1.2.1 
 * @author Olivier ROGER <roger.olivier@gmail.com>
 * @copyright  2007-2009 Prynel
 * @abstract 
 *
 */
abstract class Net_SocketBase
{
	const NB_MAX_READ_INCOMPLET=500;
	/**
	 * Adresse de connexion
	 * @var string
	 * @access private
	 */
	private $sAdresse;
	
	/**
	 * Port de connexion
	 * @var string
	 * @access private
	 */
	private $sPort;
	
	/**
	 * Socket
	 * @var ressource
	 * @access protected
	 */
	protected $sSocket;
	
	/**
	 * Temps de timeout
	 * @var int
	 * @access private
	 */
	private $sTimeout;
	
	/**
	* Constructeur. Initialise la connexion
	*
	*/
	public function __construct($adresse="localhost",$port="34000")
	{
		$this->sAdresse = $adresse;
		$this->sPort    = $port;
		$this->sTimeout = 10;
		if(!$this->sSocket  = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP))
			throw new Util_ExceptionHandler('Impossible de contacter le serveur ( '.$this->sAdresse.':'.$this->sPort.')');
		$time = time();
		socket_set_option($this->sSocket,SOL_SOCKET,SO_RCVTIMEO,array('sec'=>$this->sTimeout,'usec'=>0));
		if(!socket_connect($this->sSocket, $this->sAdresse, $this->sPort))
		{
			@socket_close($this->sSocket);
			throw new Util_ExceptionHandler('Impossible de contacter le serveur ( '.$this->sAdresse.':'.$this->sPort.')');
		}
	}
	
	/**
	 * Lecture complète des données
	 * @access protected
	 * @param $inTailleALire Entier donnant la taille du paquet à lire
	 * @return Les données lus
	 */
	protected function socket_read_complet($inTailleALire)
	{
		$nbReadIncomplet=0;
		$tailleLue = 0;
		$readIncomplet=0;
		do
		{
			$data = $data.socket_read($this->sSocket, $inTailleALire-$tailleLue);
			$tailleLue = strlen($data);
			$readIncomplet++;
		} while( ($tailleLue<$inTailleALire) && ($readIncomplet < self::NB_MAX_READ_INCOMPLET) );
		return $data;
	}
	
	protected function readChar()
	{
		return ord(socket_read($this->sSocket, 1));
	}
	
	protected function readInt()
	{
		$buff = socket_read_complet(4);
		return (ord($buff[0])+(ord($buff[1])<<8)+(ord($buff[2])<<16)+(ord($buff[3])<<24));
	}
	
	/**
	 * Ecrit un caractère sur la socket
	 *
	 * @param char $char
	 * @access protected
	 */
	protected function writeChar($char)
	{
		socket_write($this->sSocket, chr($char), 1);
	}
	
	/**
	 * Ecrit sur la socket
	 *
	 * @param string $data Données à écrire
	 * @param int $size taille à écrire
	 * @access protected
	 */
	protected function write($data)
	{
		$size = strlen($data);
		socket_write($this->sSocket, chr($data), $size);
	}
	protected function writeInt($buff)
	{
		socket_write($this->sSocket, chr((($buff)&0xFF000000)>>24), 1);
		socket_write($this->sSocket, chr((($buff)&0x00FF0000)>>16), 1);
		socket_write($this->sSocket, chr((($buff)&0x0000FF00)>>8), 1);
		socket_write($this->sSocket, chr((($buff)&0x000000FF)), 1);
	}
	
	/**
	 * Emission d'odre vers le moniteur IP
	 * @access protected
	 * @param $inOrdre Entier correspondant à l'odre d'envoi
	 */
	protected function emissionOrdre($inOrdre)
	{
		socket_write($this->sSocket, chr($inOrdre), 1); 

		if($inOrdre<128) /* Ordre sécurisé par ticket */
		{
			socket_write($this->sSocket, $_SESSION["MONIP_TICKET"], 4); 
		}
		else /* Ordre sans ticket */
		{
		}
	}
	
	/**
	 * Trnasforme une chaien, binaire en un tableau de chaine lisible
	 *
	 * @param string $inChaineBin
	 * @return string
	 */
	protected function stringBtoString($inChaineBin)
	{
		$taille = strlen($inChaineBin);
	
		for ($i=0;$i<$taille;$i++)
		{
			$chaineRetour[$i] = ord($inChaineBin[$i]);
		}
		
		return $chaineRetour;
	}
	
	/**
	* Destructeur. Termine la connexion
	* 
	*/ 
	public function __destruct()
	{
		@socket_close($this->sSocket);
	}
}
 ?>